#include<fstream>
#include<iostream>
#include<vector>
#include<algorithm>
#include<sstream>
#include<cmath>
#include<string>
#include <stdexcept>
#include <sstream>
using namespace std;

const double EPSILON = 1.0e-9; //误差范围，用于double数之间的比较
int compare_double(double a, double b)     //浮点数double比较函数，如果a>b，返回1，a==b，返回0，a<b，返回-1
{
    return (a-b) > EPSILON ? 1 : ((a-b) < -EPSILON ? -1 : 0);
}

void check_legal_line(vector<string>& subs,int &category, double &value)
{
	if (subs.size() < 2) {
        throw runtime_error("数据格式错误: 每行需要至少两个字段");
    }

    // 解析分类标识
    if (subs[0] == "Vth")       category = 2;
    else if (subs[0] == "Tsim") category = 3;
    else if (subs[0] == "dT")   category = 1;
    else if (subs[0] == "tA")    category = 4;
    else {
        throw runtime_error("未知标识: " + subs[0]);
    }

    // 解析数值
    try {
        size_t pos;
        value = stod(subs[1], &pos);
        if (pos != subs[1].size()) {
            throw invalid_argument(""); // 触发catch块
        }
    } 
	catch (const exception& e) {
        throw std::runtime_error("Invalid input ");
		return;
    }
    /*if(category == 1){
        if(value < 0)
    }*/

}

string trimLeft(const string& str) {	//剔除每行内容左端的空白字符
    size_t start = 0;
    
    while (start < str.length() && isspace(str[start])) {
        ++start;
    }
    return str.substr(start);
}
vector<string> split(const string& str) {	//将每行以空白字符为间隔分割开
    vector<string> result;
    string temp;
    istringstream stream(str);

    while (stream >> temp) {
        result.push_back(temp);
    }

    return result;
}

void readFile(double &dt, double &vth, double &tsim,int &ta, const string& filename)         //从文件中读取器件数据
{   
	ifstream infile;
	infile.open(filename);
	if (!infile.is_open()) {
        // 手动抛出异常
        throw std::runtime_error("无法打开文件: " + filename);
		return;
    }
    string buf;
	string name;
	
	int category;
	double value;
    vector<string> subs;
    buf.clear();
    while (getline(infile, buf)) //
    {  
        buf = trimLeft(buf);	//清空开头的空字符
		if(!buf.empty())
		{
			subs.clear();
			subs = split(buf);	//分割空格获得子串
			try {
                check_legal_line(subs, category, value); // 可能抛出异常
            } catch (const runtime_error& e) {
                // 添加行号信息后重新抛出
                throw_with_nested(
                    runtime_error(" 错误行: " + buf + "\n" + e.what())
            );
			}
			{
				switch (category)                       //
        		{
        			case 1:
						dt = value;
            			break;
        			case 2:
						vth = value;
            			break;
        			case 3:
						tsim = value;
            			break;
                    case 4:
                        ta = static_cast<int>(value);
        		}
			}
		}
		buf.clear();
    }
	
	if (compare_double(dt,0) <= 0||compare_double(dt,0.1) >= 0|| compare_double(vth,0) <= 0|| compare_double(vth,1) >= 0||compare_double(tsim,0) <= 0 || ta < 1 || ta > 10) {
		std::ostringstream oss;

		oss << "Invalid parameter value:";
        if (compare_double(dt,0) <= 0||compare_double(dt,0.1) >= 0)
            oss << " \ndT=" << dt;
        if(compare_double(vth,0) <= 0|| compare_double(vth,1) >= 0)
			oss<< "\nVth=" << vth;
        if(compare_double(tsim,0) <= 0)
			oss<< "\nTsim=" << tsim;
        if(ta < 1 || ta > 10)
            oss<< "\ntA=" << ta;
		throw std::runtime_error(oss.str());
	}

    infile.close();  //
}


